var Service = {
   messages: null,
   tabs: null,
   services: {},
   servicesRDF: null,
   servicesTree: null,
   statusMessage: null,
   xsltCache: null,
   prefBranch: null,
   configURL: null,
   config: null,
   autoTitle: false,
   collectionHandler: null,
   plugins: null,
   defaultType: "xhtml",
   init: function(data) {
      LOG.level = data.logLevel;
      this.xsltCache = data.xsltCache;
      this.plugins = data.plugins;
      this.collectionHandler = data.collectionHandler;
      if (data.title) {
         document.title = data.title;
      }
      if (data.service) {
         this.services[data.service.url] = data.service;
      }
      if (data.url) {
         var theClass = Components.classes["@milowski.com/atomic;1"];
         var theComponent = theClass.getService(Components.interfaces.nsISupports);
         this.atomicService = theComponent.wrappedJSObject;
         this.services[data.url] = this.atomicService.services[data.url];
         if (!this.collectionHandler) {
            this.collectionHandler = new CollectionTabs(this.services[data.url],null);
         }
      }
      this.collectionHandler.init(document,window,this.xsltCache);

      this.messages = new MessageBundle(document.getElementById('app-messages'));
      
      /*
       * Initial the RDF handling
       */
      this.servicesTree = document.getElementById('services');
      this.servicesRDF = new RDFSource(this.servicesTree.database);
      this.statusMessage = document.getElementById('status');
      
      this._updateServicesDisplay();
      
   },
   _updateServicesDisplay: function() {
      for (var url in this.services) {
         this._updateServiceDisplay(this.services[url]);
      }
   },
   notifyServiceRemoval: function(url) {
      this.servicesRDF.removeSubject(url);
      this.servicesTree.builder.rebuild();
   },
   _updateServiceDisplay: function(service) {
      var rdfDocument = null;
      if (service.loaded) {
         this._calculateLevel(service);
         LOG.logDocument(Logger.FINE,service.xml);
         rdfDocument = this.xsltCache.transformers['service2tree'].transformToDocument(service.xml);
      } else if (service.source) {
         //var serializer = new XMLSerializer();
         //alert(serializer.serializeToString(service.source));
         LOG.logDocument(Logger.FINE,service.source);
         rdfDocument = this.xsltCache.transformers['unloaded2tree'].transformToDocument(service.source);
      }
      LOG.logDocument(Logger.FINE,rdfDocument);
      this.servicesRDF.replaceSubjectFromDocument(service.url,rdfDocument);
      try {
         this.servicesTree.builder.rebuild();
      } catch (ex) {
         LOG.severe(ex);
      }
   },
   _calculateLevel: function(service) {
      var workspaces = service.xml.getElementsByTagNameNS(ATOM_PUB_INTROSPECT_NS,"workspace");
      for (var i=0; i<workspaces.length; i++) {
         var workspace = workspaces.item(i);
         var collections = service.xml.getElementsByTagNameNS(ATOM_PUB_INTROSPECT_NS,"collection");
         for (var j=0; j<collections.length; j++) {
            var href = collections[j].getAttribute("href");
            var count = 0;
            for (var k=0; k<collections.length; k++) {
               var otherHref = collections[k].getAttribute("href");
               if (j!=k && otherHref.length<=href.length && href.substring(0,otherHref.length)==otherHref) {
                  count++;
               }
            }
            collections[j].setAttribute("level",""+count);
         }
      }
   },

   _findWorkspaceAndService: function(index) {
      var id = this.servicesTree.view.getCellText(index,this.servicesTree.columns.getColumnAt(0));
      var type = this.servicesTree.view.getCellText(index,this.servicesTree.columns.getColumnAt(1));
      if (type=="service") {
         var service = this.services[id];
         return {
            service: service
         };
      } else if (type=="workspace") {
         var serviceIndex = this.servicesTree.view.getParentIndex(index);
         var serviceId  = this.servicesTree.view.getCellText(serviceIndex,this.servicesTree.columns.getColumnAt(0));
         var myService = this.services[serviceId];
         return {
            service: myService,
            workspace: myService.workspaces[id]
         };
      } else {
         var workspaceID = null;
         var current = index;
         while (!workspaceID) {
            var parent = this.servicesTree.view.getParentIndex(current);
            current = parent;
            var wid = this.servicesTree.view.getCellText(parent,this.servicesTree.columns.getColumnAt(0));
            var wtype = this.servicesTree.view.getCellText(parent,this.servicesTree.columns.getColumnAt(1));
            if (wtype=="workspace") {
               workspaceID = wid;
            }
         }
         var serviceIndex = this.servicesTree.view.getParentIndex(current);
         var serviceId  = this.servicesTree.view.getCellText(serviceIndex,this.servicesTree.columns.getColumnAt(0));
         var myService = this.services[serviceId];
         return {
            service: myService,
            workspace: myService.workspaces[workspaceID]
         };
      }
      return null;
   },

   getSelected: function() {
      if (!this.servicesTree || !this.servicesTree.view || this.servicesTree.currentIndex<0) {
         return null;
      }
      var id = this.servicesTree.view.getCellText(this.servicesTree.currentIndex,this.servicesTree.columns.getColumnAt(0));
      var type = this.servicesTree.view.getCellText(this.servicesTree.currentIndex,this.servicesTree.columns.getColumnAt(1));
      var context = this._findWorkspaceAndService(this.servicesTree.currentIndex);
      return {
         id: id,
         type: type,
         service: context.service,
         workspace: context.workspace,
         collection: type=="collection" ? context.workspace.collections[id] : null
      };
   },
   
   onServiceDoubleClick: function() {
      var id = this.servicesTree.view.getCellText(this.servicesTree.currentIndex,this.servicesTree.columns.getColumnAt(0));
      var type = this.servicesTree.view.getCellText(this.servicesTree.currentIndex,this.servicesTree.columns.getColumnAt(1));
      if (type=="collection") {
         var context = this._findWorkspaceAndService(this.servicesTree.currentIndex);
         var collection = context.workspace.collections[id];
         if (!collection.feed.xml) {
            this.collectionHandler.showLoadingCollection(collection);
            this.setStatusMessage(this.messages.format('loadingFeed',id));
            var currentApp = this;
            collection.feed.load({
               onSuccess: function() {
                  currentApp.setStatusMessage(null);
                  currentApp.collectionHandler.showCollection(collection);
               },
               onFailure: function(status,msgDoc,msgText) {
                  currentApp.setStatusMessage(null);
                  alert(currentApp.messages.format('failedToLoad',collection.url,status,msgText ? msgText.substring(0,100) : ""));
               }
            });
         } else {
            this.collectionHandler.showCollection(collection);
         }
      } else if (type=="service" && this.serviceShowHandler) {
         var context = this._findWorkspaceAndService(this.servicesTree.currentIndex);
         this.serviceShowHandler(context.service);
      }
         
   },
   
   onServiceSelect: function() {
      if (!this.servicesTree.currentIndex || this.servicesTree.currentIndex<0) {
         return;
      }
      var id = this.servicesTree.view.getCellText(this.servicesTree.currentIndex,this.servicesTree.columns.getColumnAt(0));
      var type = this.servicesTree.view.getCellText(this.servicesTree.currentIndex,this.servicesTree.columns.getColumnAt(1));
      if (type=="collection") {
         var context = this._findWorkspaceAndService(this.servicesTree.currentIndex);
         var collection = context.workspace.collections[id];
         this.setStatusMessage(collection.url);
      } else if (type=="service") {
         var context = this._findWorkspaceAndService(this.servicesTree.currentIndex);
         this.setStatusMessage(context.service.url);
      }
         
   },
   
   doCopy: function() {
      var id = this.servicesTree.view.getCellText(this.servicesTree.currentIndex,this.servicesTree.columns.getColumnAt(0));
      var type = this.servicesTree.view.getCellText(this.servicesTree.currentIndex,this.servicesTree.columns.getColumnAt(1));
      if (type=="collection") {
         this.copyTargetId = id;
         this.copyContext = this._findWorkspaceAndService(this.servicesTree.currentIndex);
      } else {
         this.copyTargetId = null;
         this.copyContext = null;
      }
   },
   
   doPaste: function() {
      if (!this.copyTargetId) {
         return;
      }
      var id = this.servicesTree.view.getCellText(this.servicesTree.currentIndex,this.servicesTree.columns.getColumnAt(0));
      var type = this.servicesTree.view.getCellText(this.servicesTree.currentIndex,this.servicesTree.columns.getColumnAt(1));
      if (id==this.copyTargetId) {
         alert("You cannot copy a feed onto itself.");
         return;
      }
      var source = this.copyContext.workspace.collections[this.copyTargetId];
      var context = this._findWorkspaceAndService(this.servicesTree.currentIndex);
      var target = context.workspace.collections[id];
      if (!confirm("Are you sure you want to copy the collection "+source.title+" to "+target.title+"?")) {
         return;
      }
      this._copyCollection(source,target);
   },
   
   _copyCollection: function(source,target)
   {
   },
   
   doDelete: function() {
      //alert("doDelete in Service.js");
      var id = this.servicesTree.view.getCellText(this.servicesTree.currentIndex,this.servicesTree.columns.getColumnAt(0));
      var type = this.servicesTree.view.getCellText(this.servicesTree.currentIndex,this.servicesTree.columns.getColumnAt(1));
      if (type=="collection") {
         var context = this._findWorkspaceAndService(this.servicesTree.currentIndex);
         var collection = context.workspace.collections[id];
         if (confirm("Are you sure you want to delete the collection "+collection.url)) {
            var currentApp = this;
            this.setStatusMessage("Deleting collection...");
            context.workspace.removeByDelete(collection, {
               timeout: _TIMEOUT_,
               onSuccess: function() {
                  currentApp.setStatusMessage();
                  //currentApp.servicesRDF.removeResource(context.workspace.service.url,context.workspace.id,collection.url);
                  currentApp._updateServiceDisplay(context.workspace.service);
               },
               onFailure: function(status,message) {
                  alert("("+status+") "+message);
               }
            });
         }
      }
   },
   newCollection: function() {
      var id = this.servicesTree.view.getCellText(this.servicesTree.currentIndex,this.servicesTree.columns.getColumnAt(0));
      var type = this.servicesTree.view.getCellText(this.servicesTree.currentIndex,this.servicesTree.columns.getColumnAt(1));
      if (type=="service") {
         alert("Creating new workspaces is not supported.");
         return;
      }
      var context = this._findWorkspaceAndService(this.servicesTree.currentIndex);
      var href = id;
      var workspaceHasChildren = false;
      if (type=="workspace") {
         try {
            var nextType = this.servicesTree.view.getCellText(this.servicesTree.currentIndex+1,this.servicesTree.columns.getColumnAt(1));
            if (nextType=="collection") {
               href = this.servicesTree.view.getCellText(this.servicesTree.currentIndex+1,this.servicesTree.columns.getColumnAt(0));
            } else {
               var parent = this.servicesTree.view.getParentIndex(this.servicesTree.currentIndex);
               href = this.servicesTree.view.getCellText(parent,this.servicesTree.columns.getColumnAt(0));
            }
            workspaceHasChildren = true;
         } catch (ex) {
            var parent = this.servicesTree.view.getParentIndex(this.servicesTree.currentIndex);
            href = this.servicesTree.view.getCellText(parent,this.servicesTree.columns.getColumnAt(0));
         }
      }
      if (type=="collection" || type=="workspace") {
         var url = href;
         if (href.substring(href.length-1)=="/") {
            if (type=="workspace" && !workspaceHasChildren) {
               url += "R";
            } else {
               url += "newcollection";
            }
         } else {
            if (type=="workspace" && !workspaceHasChildren) {
               url += "/R";
            } else {
               url += "/newcollection";
            }
         }
         var data = {
            url: url,
            title: "feed title"
         };
         window.openDialog("chrome://atomic/content/new-collection.xul","new collection","chrome,resizable,modal",data);
         if (data.save) {
            var currentApp = this;
            this.setStatusMessage("Creating feed "+data.title);
            var collection = context.workspace.newCollection(data.url,data.title);
            context.workspace.createByPost(collection,{
               timeout: _TIMEOUT_,
               onSuccess: function() {
                  currentApp.setStatusMessage();
                  currentApp._updateServiceDisplay(context.workspace.service);
               },
               onFailure: function(status) {
                  currentApp.setStatusMessage();
                  alert("Cannot create collection due to error "+status);
               }
            });
         }
      }
   },
   reloadCollection: function() {
      var id = this.servicesTree.view.getCellText(this.servicesTree.currentIndex,this.servicesTree.columns.getColumnAt(0));
      var type = this.servicesTree.view.getCellText(this.servicesTree.currentIndex,this.servicesTree.columns.getColumnAt(1));
      if (type!="collection") {
         return;
      }
      var context = this._findWorkspaceAndService(this.servicesTree.currentIndex);
      var collection = context.workspace.collections[id];
      var tabinfo = this._getCollectionTab(collection.url);
      if (tabinfo) {
         var tabsContainer = this.contentTabs.getElementsByTagName("tabs").item(0);
         var tabpanels = this.contentTabs.getElementsByTagName("tabpanels").item(0);
         if (this.contentTabs.selectedTab==tabinfo.tab) {
            var dir = this.contentTabs.selectedIndex==0 ? 1 : -1
            tabsContainer.advanceSelectedTab(dir,true);
         }
         tabsContainer.removeChild(tabinfo.tab);
         tabpanels.removeChild(tabinfo.panel);
      }
      
      this.setStatusMessage(this.messages.format('loadingFeed',id));
      var currentApp = this;
      collection.feed.load({
         onSuccess: function() {
            currentApp.setStatusMessage(null);
            if (tabinfo) {
               currentApp.showCollection(collection);
            }
         },
         onFailure: function(status,msgDoc) {
            currentApp.setStatusMessage(null);
            alert(currentApp.messages.format('failedToLoad',collection.url,status,msgDoc.substring(0,100)));
         }
      });
   },
   setStatusMessage: function(message){
      DOMUtil.clearChildren(this.statusMessage);
      if (message) {
         this.statusMessage.appendChild(this.statusMessage.ownerDocument.createTextNode(message));
      }
   }
}
